﻿using BeetleX.Dispatchs;
using BeetleX.EventArgs;
using System;
using System.IO;
using System.Text;

#nullable disable
namespace BeetleX.XRPC
{
    public class FileLogWriter
    {
        private string mLogPath;
        private int FileIndex;
        private SingleThreadDispatcher<FileLogWriter.LogItem> mDispatcher;
        private StreamWriter mWriter;
        private int mWriteCount;

        public FileLogWriter(string type)
        {
            this.Type = type;
            this.mLogPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString() + "logs" + Path.DirectorySeparatorChar.ToString();
            if (!Directory.Exists(this.mLogPath))
                Directory.CreateDirectory(this.mLogPath);
            this.mDispatcher = new SingleThreadDispatcher<FileLogWriter.LogItem>(new Action<FileLogWriter.LogItem>(this.OnWriteLog));
        }

        public string Type { get; private set; }

        protected StreamWriter GetWriter()
        {
            if (this.mWriter == null || this.mWriter.BaseStream.Length > 20971520L)
            {
                if (this.mWriter != null)
                {
                    this.mWriter.Flush();
                    this.mWriter.Close();
                }
                string path;
                do
                {
                    path = this.mLogPath + this.Type + "_" + DateTime.Now.ToString("yyyyMMdd") + "_" + (++this.FileIndex).ToString() + ".txt";
                }
                while (File.Exists(path));
                this.mWriter = new StreamWriter(path, false, Encoding.UTF8);
            }
            return this.mWriter;
        }

        private void OnWriteLog(FileLogWriter.LogItem e)
        {
            ++this.mWriteCount;
            StreamWriter writer = this.GetWriter();
            writer.Write("[");
            writer.Write((object)DateTime.Now);
            writer.Write("] [");
            writer.Write(e.Type.ToString());
            writer.Write("] ");
            writer.WriteLine(e.Message);
            if (this.mWriteCount <= 200 && this.mDispatcher.Count != 0)
                return;
            writer.Flush();
            this.mWriteCount = 0;
        }

        public void Add(LogType type, string message)
        {
            this.Add(new FileLogWriter.LogItem(type, message));
        }

        public void Add(FileLogWriter.LogItem e) => this.mDispatcher.Enqueue(e);

        public void Run()
        {
        }

        public class LogItem
        {
            public LogType Type;
            public string Message;

            public LogItem(LogType type, string message)
            {
                this.Type = type;
                this.Message = message;
            }
        }
    }
}
